unit TaskList;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,ComCtrls, ExtCtrls, StdCtrls,
  wsMain,wsClasses,wsDB,wsControls,wsDiagram, atDiagram, LiveDiagram;

type
  TFormTaskList = class(TForm)
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    WorkflowDiagram1: TWorkflowDiagram;
    TabSheet2: TTabSheet;
    lvTasks: TTaskListView;
    Timer1: TTimer;
    TabSheet3: TTabSheet;
    Panel1: TPanel;
    Label1: TLabel;
    lbSubject: TLabel;
    Panel2: TPanel;
    Label2: TLabel;
    lbExpiration: TLabel;
    cbTaskStatus: TTaskStatusCombo;
    mmDescription: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure lvTasksCustomDrawItem(Sender: TCustomListView;
      Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
    procedure lvTasksSelectItem(Sender: TObject; Item: TListItem;
      Selected: Boolean);
    procedure Timer1Timer(Sender: TObject);
    procedure WorkflowDiagram1Click(Sender: TObject);
  private
    { Private declarations }
    FWorkIns: TWorkflowInstance;
    FLastActivePageName: string;
    FUpdatingTabs: integer;
    FFieldPanel: TTaskFieldPanel;
    FLogView: TTaskLogListView;
    FFreeOnClose: boolean;
    FWorkflowStudio: TWorkflowStudio;
    FOldRunFinished: TWorkflowInstanceEvent;

    procedure RunFinished(Sender: TObject; AWorkIns: TWorkflowInstance);
     procedure UpdateWorkflowDiagram;
     function GetWorkIns: TWorkflowInstance;
  public
    { Public declarations }
    constructor Create(AOwner: TComponent; AWorkflowStudio: TWorkflowStudio); reintroduce;
    destructor Destroy; override;

    procedure LoadData;
    procedure SetFilter(FilterType: TTaskFilterType; AFilter: string);
  end;

var
  FormTaskList: TFormTaskList;

implementation
uses wsRes;
{$R *.dfm}

constructor TFormTaskList.Create(AOwner: TComponent;
  AWorkflowStudio: TWorkflowStudio);
begin
  inherited Create(AOwner);
  if AWorkflowStudio <> nil then
    FWorkflowStudio := AWorkflowStudio
  else
    raise Exception.CreateFmt('WorkflowStudio parameter not specified in %s.Create.', [ClassName]);

  WorkflowDiagram1.WorkflowStudio := FWorkflowStudio;
  lvTasks.WorkflowStudio := FWorkflowStudio;
  FOldRunFinished := FWorkflowStudio.OnRunFinished;
  FWorkflowStudio.OnRunFinished := RunFinished;
end;

destructor TFormTaskList.Destroy;
begin
  FWorkflowStudio.OnRunFinished := FOldRunFinished;
  inherited;
end;

procedure TFormTaskList.FormCreate(Sender: TObject);
begin
{  //frTaskView.OnTaskChanged := TaskEdited;
  FFieldPanel := TTaskFieldPanel.Create(Self);
  FFieldPanel.Parent := TabControl1;
  FFieldPanel.Align := alClient;

  FLogView := TTaskLogListView.Create(Self);
  FLogView.WorkflowStudio := FWorkflowStudio;
  FLogView.Parent := TabControl1;
  FLogView.Align := alClient;

  FUpdatingTabs := 0;
  frTaskView.Task := nil;
}

  {Create list view columns}
  lvTasks.Columns.Clear;
  With lvTasks.Columns.Add do
  begin
    Caption := _str(SColumnKey);
    Width := 40;
  end;
  With lvTasks.Columns.Add do
  begin
    Caption := _str(SColumnName);
    Width := 100;
  end;
  With lvTasks.Columns.Add do
  begin
    Caption := _str(SColumnWorkflow);
    Width := 100;
  end;
  With lvTasks.Columns.Add do
  begin
    Caption := _str(SColumnSubject);
    Width := 220;
  end;
  With lvTasks.Columns.Add do
  begin
    Caption := _str(SColumnStatus);
    Width := 100;
  end;
  With lvTasks.Columns.Add do
  begin
    Caption := _str(SColumnUser);
    Width := 100;
  end;

end;

procedure TFormTaskList.LoadData;
begin
  lvTasks.LoadFromDatabase;
  if lvTasks.SelectedTask = nil then
  begin
    if lvTasks.Items.Count > 0 then
      lvTasks.Items.Item[0].Selected := true
    else
      lvTasksSelectItem(nil, nil, false);
  end;
end;

procedure TFormTaskList.RunFinished(Sender: TObject;
  AWorkIns: TWorkflowInstance);
begin
  LoadData;
  if Assigned(FOldRunFinished) then
    FOldRunFinished(Sender, AWorkIns);
end;

procedure TFormTaskList.SetFilter(FilterType: TTaskFilterType;
  AFilter: string);
begin
  lvTasks.FilterType := FilterType;
  lvTasks.FilterKey := AFilter;
end;

procedure TFormTaskList.FormShow(Sender: TObject);
begin
  UpdateWorkflowDiagram;

end;

procedure TFormTaskList.UpdateWorkflowDiagram;
var
  AWorkIns: TWorkflowInstance;
begin
  if (lvTasks.SelectedTask <> nil) or (lvTasks.FilterType = tfWorkIns) then
  begin
    WorkflowDiagram1.BeginUpdate;
    try
      AWorkIns := GetWorkIns;
      AWorkIns.AssignToDiagram(WorkflowDiagram1, true);
      WorkflowDiagram1.DisplayTaskStatus := true;

      Case AWorkIns.Status of
        wsNotStarted:
          WorkflowDiagram1.ViewStateMode := vmStart;
        wsFinished, wsFinishedWithError:
          WorkflowDiagram1.ViewStateMode := vmEnd;
      else
          WorkflowDiagram1.ViewStateMode := vmRun;
      end;

      WorkflowDiagram1.TopRuler.Visible := false;
      WorkflowDiagram1.LeftRuler.Visible := false;
      WorkflowDiagram1.AutoPage := false;
      WorkflowDiagram1.AutoScroll := true;
      WorkflowDiagram1.PageLines.Visible := false;
      WorkflowDiagram1.State := dsView;
      WorkflowDiagram1.MakeActiveNodeVisible;
    finally
      WorkflowDiagram1.EndUpdate;
    end;
  end
  else
    WorkflowDiagram1.Clear;

end;

function TFormTaskList.GetWorkIns: TWorkflowInstance;
begin
  {Check if WorkIns is already loaded}
  if FWorkIns <> nil then
  begin
    case lvTasks.FilterType of
      tfWorkIns:
        if FWorkIns.Key = lvTasks.FilterKey then
        begin
          result := FWorkIns;
          exit;
        end;
    else
      begin
        if (lvTasks.SelectedTask <> nil) and (FWorkIns.Key = lvTasks.SelectedTask.WorkInsKey) then
        begin
          result := FWorkIns;
          exit;
        end;
      end;
    end;
  end;

  {FWorkIns must be reloaded}
  if FWorkIns <> nil then
    FWorkIns.Free;

  FWorkIns := TWorkflowInstance.Create(nil, FWorkflowStudio);
  if lvTasks.FilterType = tfWorkIns then
    FWorkIns.Key := lvTasks.FilterKey {workInskey}
  else
    if lvTasks.SelectedTask <> nil then
      FWorkIns.Key := lvTasks.SelectedTask.WorkInsKey
    else
    begin
      FWorkIns.Free;
      FWorkIns := nil;
    end;

  FWorkflowStudio.WorkflowManager.LoadWorkflowInstance(FWorkIns);
  result := FWorkIns;
end;

procedure TFormTaskList.lvTasksCustomDrawItem(Sender: TCustomListView;
  Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
var
  ATask: TTaskInstance;
begin
  ATask := nil;
  if Item <> nil then
    ATask := lvTasks.TaskFromItem(Item);
  if ATask <> nil then
  begin
    if ATask.Completed then
      lvTasks.Canvas.Font.Color := clGray;
  end;
  DefaultDraw := true;

end;

procedure TFormTaskList.lvTasksSelectItem(Sender: TObject; Item: TListItem;
  Selected: Boolean);
begin
  Timer1.Enabled := false;
  Timer1.Enabled := true;
end;

procedure TFormTaskList.Timer1Timer(Sender: TObject);
begin
  Timer1.Enabled := false;
  if (not (csDestroying in ComponentState)) then
  begin
      UpdateWorkflowDiagram;
(*    {Save last active page name}
    if TabControl1.TabIndex > -1 then
      FLastActivePageName := TabControl1.Tabs[TabControl1.TabIndex];

    BeginUpdateTabs;
    try
      frTaskView.Task := lvTasks.SelectedTask;
      if lvTasks.SelectedTask <> nil then
        frTaskView.ExpirationDateTime := FWorkflowStudio.TaskManager.TaskExpirationDateTime(GetWorkIns, lvTasks.SelectedTask)
      else
        frTaskView.ExpirationDateTime := 0;

      UpdateWorkflowDiagram;
      UpdateAttachmentTabs;

      {The following methods *must* be called in that order}
      UpdateFixedTabs;
      UpdateFieldsTab;
      UpdateLogTab;

      if lvTasks.SelectedTask <> nil then
      begin
        {Recover the active page}
        TabControl1.TabIndex := TabControl1.Tabs.IndexOf(FLastActivePageName);
      end;
      btSaveChanges.Enabled := (lvTasks.SelectedTask <> nil) and not lvTasks.SelectedTask.Completed
        and lvTasks.SelectedTask.CanUpdate(FWorkflowStudio.UserManager.LoggedUserId, FWorkflowStudio);

    finally
      EndUpdateTabs;
    end;

    UpdateActivePage;
    *)
  end;

end;

procedure TFormTaskList.WorkflowDiagram1Click(Sender: TObject);
begin
  WorkflowDiagram1.SetFocus;
end;

end.
